package com.fengniu.ejb.business.impl;

import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

import org.jboss.ejb3.annotation.LocalBinding;
import org.jboss.ejb3.annotation.RemoteBinding;

import com.fengniu.ejb.business.IUserBusinessLocal;
import com.fengniu.ejb.business.IUserBusinessRemote;
import com.fengniu.ejb.dao.CategoryDaoLocal;
import com.fengniu.ejb.dao.ContentDaoLocal;
import com.fengniu.ejb.dao.DeltaDaoLocal;
import com.fengniu.ejb.dao.SiteDaoLocal;
import com.fengniu.ejb.dao.UserDaoLocal;
import com.fengniu.ejb.dao.util.IEJBConstants;
import com.fengniu.ejb.entity.Category;
import com.fengniu.ejb.entity.Content;
import com.fengniu.ejb.entity.Content2Category;
import com.fengniu.ejb.entity.DeltaRelation;
import com.fengniu.ejb.entity.Site;
import com.fengniu.ejb.entity.Site2Category;
import com.fengniu.ejb.entity.Site2Content;
import com.fengniu.ejb.entity.Site2Site;
import com.fengniu.ejb.entity.TagLog;
import com.fengniu.ejb.entity.User;
import com.fengniu.ejb.entity.User2Content;
import com.fengniu.ejb.entity.User2Site;
import com.fengniu.ejb.entity.User2User;
import com.tianbing.adlottery.global.IConstants;

@Stateless
@LocalBinding(jndiBinding = IEJBConstants.UserBusinessLocalJndiName)
@RemoteBinding(jndiBinding = IEJBConstants.UserBusinessRemoteJndiName)
public class UserBusinessImpl implements IUserBusinessLocal, IUserBusinessRemote {

	@EJB(name = IEJBConstants.UserDaoLocalJndiName)
	private UserDaoLocal userDao;

	@EJB(name = IEJBConstants.SiteDaoLocalJndiName)
	private SiteDaoLocal siteDao;

	@EJB(name = IEJBConstants.ContentDaoLocalJndiName)
	private ContentDaoLocal contentDao;

	@EJB(name = IEJBConstants.CategoryDaoLocalJndiName)
	private CategoryDaoLocal categoryDao;

	@EJB(name = IEJBConstants.DeltaDaoLocalJndiName)
	private DeltaDaoLocal deltaUCSGRelationDao;

	/**
	 * create user 2 coupon relations
	 * 
	 * @param userSysId
	 * @param id
	 * @param contentSysIds
	 */
	public void addUser2Contents(long userSysId, Integer relationId, long[] contentSysIds) {
		User u = userDao.findUserBySysId(userSysId);
		if (u != null) {
			for (int i = 0; i < contentSysIds.length; i++) {
				Content c = contentDao.findContentBySysId(contentSysIds[i]);
				if (c != null) {
					// Create relation of user 2 coupon
					User2Content u2c = userDao.findUser2ContentBy(u.getUserId(), relationId, c.getContentId());
					if (u2c == null) {
						u2c = new User2Content();
						u2c.setUser(u);
						u2c.setRelationId(relationId);
						u2c.setContent(c);
						userDao.saveUser2Content(u2c);
					}
				}
			}
		}
	}

	/**
	 * create user 2 coupon relations,typically used for creating user 2 words
	 * 
	 * @param userId
	 * @param id
	 * @param contentIds
	 */
	public void addUser2Contents(String userId, Integer relationId, String[] contentIds) {
		User u = userDao.findUserByUserId(userId);
		if (u != null) {
			for (int i = 0; i < contentIds.length; i++) {
				Content c = contentDao.findContentByContentId(contentIds[i]);
				// TODO should implement with translation to check unique
				// contentId
				// Save word if the word is not exist in dictionary
				if (c == null) {
					c = new Content();
					c.setContentId(contentIds[i]);
					c.setName(contentIds[i]);
					c = contentDao.saveContent(c);
				}
				// Create relation of user 2 coupon
				User2Content u2c = userDao.findUser2ContentBy(userId, relationId, contentIds[i]);
				if (u2c == null) {
					u2c = new User2Content();
					u2c.setUser(u);
					u2c.setRelationId(relationId);
					u2c.setContent(c);
					userDao.saveUser2Content(u2c);
				}
			}
		}
	}

	public void setUserDao(UserDaoLocal userDao) {
		this.userDao = userDao;
	}

	public void setContentDao(ContentDaoLocal contentDao) {
		this.contentDao = contentDao;
	}

	public void deleteUser2Contents(long userSysId, Integer relationId, long[] contentSysIds) {
		userDao.deleteUser2Contents(userSysId, relationId, contentSysIds);
	}

	public Site findUserManagedStore(long userSysId) {
		Site result = null;
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_OWNER_OF.getId() };
		Integer[] siteTypeIds = { IConstants.Type.SITE_STORE.getId() };
		List<User2Site> u2sList = userDao.getListUser2SiteBy(userSysId, relationIds, -1, null, siteTypeIds, 0, 1, null);
		if (u2sList != null && u2sList.size() > 0)
			result = u2sList.get(0).getSite();
		return result;
	}

	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void saveUserManagedStore(long userSysId, Site pSite, String initStorePositionCategoryId) {
		User user = userDao.findUserBySysId(userSysId);
		if (user != null && pSite != null && pSite.getSiteId() != null) {
			Site manSite = findUserManagedStore(userSysId);
			if (manSite == null) {
				if (initStorePositionCategoryId != null) {
					Category category = categoryDao.findCategoryByCategoryId(initStorePositionCategoryId);
					if (category != null) {
						pSite.setTypeId(IConstants.Type.SITE_STORE.getId());
						Site site = siteDao.saveSite(pSite);
						// save user2site
						User2Site u2s = new User2Site();
						u2s.setUser(user);
						u2s.setRelationId(IConstants.RelationID.U2S_IS_OWNER_OF.getId());
						u2s.setSite(site);
						userDao.saveUser2Site(u2s);
						// save site2Category
						Site2Category s2g = new Site2Category();
						s2g.setSite(site);
						s2g.setRelationId(IConstants.RelationID.S2G_IS_MEMBER_OF.getId());
						s2g.setCategory(category);
						siteDao.saveSite2Category(s2g);
					}
				}
			} else if (manSite.getSysId().compareTo(pSite.getSysId()) == 0) {
				siteDao.saveSite(pSite);
			}
		}
	}

	public Site findUserManagedCompany(long userSysId) {
		Site result = null;
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_OWNER_OF.getId() };
		Integer[] siteTypeIds = { IConstants.Type.SITE_COMPANY.getId() };
		List<User2Site> u2sList = userDao.getListUser2SiteBy(userSysId, relationIds, -1, null, siteTypeIds, 0, 1, null);
		if (u2sList != null && u2sList.size() > 0)
			result = u2sList.get(0).getSite();
		return result;
	}

	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void saveUserManagedCompany(long userSysId, Site pSite) {
		User user = userDao.findUserBySysId(userSysId);
		if (user != null && pSite != null && pSite.getSiteId() != null) {
			Site manSite = findUserManagedCompany(userSysId);
			if (manSite == null) {
				pSite.setTypeId(IConstants.Type.SITE_COMPANY.getId());
				Site site = siteDao.saveSite(pSite);
				// save user2site
				User2Site u2s = new User2Site();
				u2s.setUser(user);
				u2s.setRelationId(IConstants.RelationID.U2S_IS_OWNER_OF.getId());
				u2s.setSite(site);
				userDao.saveUser2Site(u2s);
			} else if (manSite.getSysId().compareTo(pSite.getSysId()) == 0) {
				siteDao.saveSite(pSite);
			}
		}
	}

	public void addUserFavoriteCompany(long userSysId, long siteSysId) {
		// TODO should limit favorite company number,check whether it is already
		// exist

		Site c = siteDao.findSiteBySysId(siteSysId);
		if (c != null && c.getTypeId().compareTo(IConstants.Type.SITE_COMPANY.getId()) == 0) {
			Integer[] relationIds = { IConstants.RelationID.U2S_IS_FAVORITER_OF.getId() };

			List<User2Site> u2cs = userDao
					.getListUser2SiteBy(userSysId, relationIds, siteSysId, null, null, 0, 1, null);
			if (u2cs != null && u2cs.size() > 0) {
				User2Site u2c = u2cs.get(0);
				if (u2c.getStatus() != IConstants.Status.IS_APPROVE_SUCC.getId()) {
					u2c.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
				}
			} else {// create new User2Site
				User u = userDao.findUserBySysId(userSysId);
				if (u != null) {
					User2Site u2c = new User2Site();
					u2c.setUser(u);
					u2c.setRelationId(IConstants.RelationID.U2S_IS_FAVORITER_OF.getId());
					u2c.setSite(c);
					u2c.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
					userDao.saveUser2Site(u2c);
				}

			}
		}

	}

	public void addUserFavoriteStore(long userSysId, long siteSysId) {
		// TODO should limit favorite store number,check whether it is already
		// exist

		Site c = siteDao.findSiteBySysId(siteSysId);
		if (c != null && c.getTypeId().compareTo(IConstants.Type.SITE_STORE.getId()) == 0) {
			Integer[] relationIds = { IConstants.RelationID.U2S_IS_FAVORITER_OF.getId() };

			List<User2Site> u2ss = userDao
					.getListUser2SiteBy(userSysId, relationIds, siteSysId, null, null, 0, 1, null);
			if (u2ss != null && u2ss.size() > 0) {
				User2Site u2s = u2ss.get(0);
				if (u2s.getStatus() != IConstants.Status.IS_APPROVE_SUCC.getId()) {
					u2s.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
				}
			} else {// create new User2Site
				User u = userDao.findUserBySysId(userSysId);
				if (u != null) {
					User2Site u2c = new User2Site();
					u2c.setUser(u);
					u2c.setRelationId(IConstants.RelationID.U2S_IS_FAVORITER_OF.getId());
					u2c.setSite(c);
					u2c.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
					userDao.saveUser2Site(u2c);
				}

			}
		}
	}

	public void addUserFavoriteHorde(long userSysId, long siteSysId) {
		// TODO should limit favorite store number,check whether it is already
		// exist

		Site c = siteDao.findSiteBySysId(siteSysId);
		if (c != null && c.getTypeId().compareTo(IConstants.Type.SITE_HORDE.getId()) == 0) {
			Integer[] relationIds = { IConstants.RelationID.U2S_IS_FAVORITER_OF.getId() };

			List<User2Site> u2ss = userDao
					.getListUser2SiteBy(userSysId, relationIds, siteSysId, null, null, 0, 1, null);
			if (u2ss != null && u2ss.size() > 0) {
				User2Site u2s = u2ss.get(0);
				if (u2s.getStatus() != IConstants.Status.IS_APPROVE_SUCC.getId()) {
					u2s.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
				}
			} else {// create new User2Site
				User u = userDao.findUserBySysId(userSysId);
				if (u != null) {
					User2Site u2c = new User2Site();
					u2c.setUser(u);
					u2c.setRelationId(IConstants.RelationID.U2S_IS_FAVORITER_OF.getId());
					u2c.setSite(c);
					u2c.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
					userDao.saveUser2Site(u2c);
				}

			}
		}
	}

	public void addUserFavoriteProduct(long userSysId, long contentSysId) {
		// TODO should limit favorite product number,check whether it is already
		// exist

		Integer[] relationIds = { IConstants.RelationID.U2C_IS_FAVORITER_OF.getId() };

		List<User2Content> u2cs = userDao.getListUser2ContentBy(userSysId, relationIds, contentSysId, null, null, null,
				0, 1, null);
		if (u2cs != null && u2cs.size() > 0) {
			User2Content u2c = u2cs.get(0);
			if (u2c.getStatus().compareTo(IConstants.Status.IS_APPROVE_SUCC.getId()) != 0) {
				u2c.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
			}
		} else {// create new User2Content
			User u = userDao.findUserBySysId(userSysId);
			if (u != null) {
				Content c = contentDao.findContentBySysId(contentSysId);
				if (c != null) {
					User2Content u2c = new User2Content();
					u2c.setUser(u);
					u2c.setRelationId(IConstants.RelationID.U2C_IS_FAVORITER_OF.getId());
					u2c.setContent(c);
					u2c.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
					userDao.saveUser2Content(u2c);
				}
			}

		}

	}

	public void deleteUserFavoriteCompany(long userSysId, long siteSysId) {
		// update the User2Site status to deleted.
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_FAVORITER_OF.getId() };
		Integer[] siteTypeIds = { IConstants.Type.SITE_COMPANY.getId() };
		List<User2Site> u2ss = userDao.getListUser2SiteBy(userSysId, relationIds, siteSysId, null, siteTypeIds, 0, 1,
				null);
		if (u2ss != null && u2ss.size() > 0) {
			User2Site u2s = u2ss.get(0);
			u2s.setStatus(IConstants.Status.IS_APPROVE_FAIL.getId());
			userDao.saveUser2Site(u2s);
		}
	}

	public void deleteUserFavoriteProduct(long userSysId, long contentSysId) {
		// update the User2Site status to deleted.
		Integer[] relationIds = { IConstants.RelationID.U2C_IS_FAVORITER_OF.getId() };
		List<User2Content> u2cs = userDao.getListUser2ContentBy(userSysId, relationIds, contentSysId, null, null, null,
				0, 1, null);
		if (u2cs != null && u2cs.size() > 0) {
			User2Content u2s = u2cs.get(0);
			u2s.setStatus(IConstants.Status.IS_APPROVE_FAIL.getId());
			userDao.saveUser2Content(u2s);
		}
	}

	public void deleteUserFavoriteStore(long userSysId, long siteSysId) {
		// update the User2Site status to deleted.
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_FAVORITER_OF.getId() };
		Integer[] siteTypeIds = { IConstants.Type.SITE_STORE.getId() };
		List<User2Site> u2ss = userDao.getListUser2SiteBy(userSysId, relationIds, siteSysId, null, siteTypeIds, 0, 1,
				null);
		if (u2ss != null && u2ss.size() > 0) {
			User2Site u2s = u2ss.get(0);
			u2s.setStatus(IConstants.Status.IS_APPROVE_FAIL.getId());
			userDao.saveUser2Site(u2s);
		}
	}

	public List<User2Content> getListUserFavoriteProduct(long userSysId, long contentSysId, int pgno, int pgsize) {
		Integer[] relationIds = { IConstants.RelationID.U2C_IS_FAVORITER_OF.getId() };
		Integer[] statusIds = null;// {
		// IConstants.Status.IS_APPROVE_SUCC.getId()
		// };

		List<User2Content> u2cs = userDao.getListUser2ContentBy(userSysId, relationIds, contentSysId, statusIds, null,
				null, pgno, pgsize, null);
		return u2cs;
	}

	public List<User2Content> getListUserFloatBook(long userSysId, long contentSysId, int pgno, int pgsize) {
		Integer[] relationIds = { IConstants.RelationID.U2C_IS_FLOATER_OF.getId() };
		Integer[] statusIds = null;// {
		// IConstants.Status.IS_APPROVE_SUCC.getId()
		// };

		List<User2Content> u2cs = userDao.getListUser2ContentBy(userSysId, relationIds, contentSysId, statusIds, null,
				null, pgno, pgsize, null);
		return u2cs;
	}

	public List<User2Site> getListUserFavoriteCompany(long userSysId, long siteSysId, int pgno, int pgsize) {
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_FAVORITER_OF.getId() };
		Integer[] statusIds = null;// {
		// IConstants.Status.IS_APPROVE_SUCC.getId()
		// };
		Integer[] siteTypeIds = { IConstants.Type.SITE_COMPANY.getId() };

		List<User2Site> u2cs = userDao.getListUser2SiteBy(userSysId, relationIds, siteSysId, statusIds, siteTypeIds,
				pgno, pgsize, null);
		return u2cs;
	}

	public List<User2Site> getListUserFavoriteStore(long userSysId, long siteSysId, int pgno, int pgsize) {
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_FAVORITER_OF.getId() };
		Integer[] statusIds = null;// {
		// IConstants.Status.IS_APPROVE_SUCC.getId()
		// };
		Integer[] siteTypeIds = { IConstants.Type.SITE_STORE.getId() };

		List<User2Site> u2cs = userDao.getListUser2SiteBy(userSysId, relationIds, siteSysId, statusIds, siteTypeIds,
				pgno, pgsize, null);
		return u2cs;
	}

	public List<User2Site> getListUserFavoriteHorde(long userSysId, long siteSysId, int pgno, int pgsize) {
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_FAVORITER_OF.getId() };
		Integer[] statusIds = null;// {
		// IConstants.Status.IS_APPROVE_SUCC.getId()
		// };
		Integer[] siteTypeIds = { IConstants.Type.SITE_HORDE.getId() };

		List<User2Site> u2cs = userDao.getListUser2SiteBy(userSysId, relationIds, siteSysId, statusIds, siteTypeIds,
				pgno, pgsize, null);
		return u2cs;
	}

	public List<User2Site> getListUserFavoriteWebSite(long userSysId, long siteSysId, int pgno, int pgsize) {
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_FAVORITER_OF.getId() };
		Integer[] statusIds = { IConstants.Status.IS_APPROVE_SUCC.getId() };
		Integer[] siteTypeIds = { IConstants.Type.SITE_WEBSITE.getId() };

		List<User2Site> u2cs = userDao.getListUser2SiteBy(userSysId, relationIds, siteSysId, statusIds, siteTypeIds,
				pgno, pgsize, null);
		return u2cs;
	}

	public void saveUserCompanyProductRequest(long userSysId, User2Site user2Site) {
		User user = userDao.findUserBySysId(userSysId);
		if (user != null) {
			User2Site u2s = userDao.findUser2SiteBy(user.getUserId(), IConstants.RelationID.U2S_IS_PRODUCT_REQUESTER_OF
					.getId(), user2Site.getSite().getSiteId());
			if (u2s == null) {
				user2Site.setUser(user);
				user2Site.setRelationId(IConstants.RelationID.U2S_IS_PRODUCT_REQUESTER_OF.getId());
				userDao.saveUser2Site(user2Site);
			}
		}
	}

	public void updateUserSaleContents(User2Content user2Content, long[] delegatedStoreSysIds) {
		if (user2Content != null) {
			user2Content = userDao.saveUser2Content(user2Content);
			cleanUser2ContentDelegatedSites(user2Content.getSysId());
			// for (int i = 0; i < delegatedStoreSysIds.length; i++) {
			// Site s = siteDao.findSiteBySysId(delegatedStoreSysIds[i]);
			// if (s != null) {
			// Site2User_Content u2c2s =
			// userDao.findUser2Content2Site(user2Content.getSysId(),
			// IConstants.RelationID.U2C2S_DELEGATED_SALE_OF.getId(),
			// s.getSysId());
			// //保存托售商店的关系
			// if (u2c2s == null) {
			// u2c2s = new Site2User_Content();
			// u2c2s.setUser2Content(user2Content);
			// u2c2s.setRelationId(IConstants.RelationID.U2C2S_DELEGATED_SALE_OF.getId());
			// u2c2s.setSite(s);
			// userDao.saveUser2Content2Site(u2c2s);
			// }
			// }
			// }
		}

	}

	/**
	 * clean delegated relations to stores
	 * 
	 * @param user2Content2SiteSysId
	 */
	private void cleanUser2ContentDelegatedSites(long user2Content2SiteSysId) {
		userDao.deleteUser2Content2Sites(user2Content2SiteSysId, IConstants.RelationID.U2C2S_DELEGATED_SALE_OF.getId(),
				null);
	}

	// public List<Site2User_Content> getListUser2ContentDelegatedSite(long
	// user2ContentSysId, int pgno, int pgsize) {
	// Integer[] relationIds = {
	// IConstants.RelationID.U2C2S_DELEGATED_SALE_OF.getId() };
	// return userDao.getListUser2Content2SiteBy(user2ContentSysId, relationIds,
	// -1, pgno, pgsize, null);
	// }

	public void saveUserPostMessage(long userSysId, Content content, long[] post2SiteSysIds) {
		User user = userDao.findUserBySysId(userSysId);
		if (content != null
				&& (content.getTypeId() == null || content.getTypeId() == IConstants.Type.CONTENT_MESSAGE.getId())
				&& user != null) {
			if (content.getContentId() == null) {
				// new posted message
				Calendar now = Calendar.getInstance();
				String contentId = userSysId + "_" + now.getTimeInMillis();
				content.setContentId(contentId);
				content.setTypeId(IConstants.Type.CONTENT_MESSAGE.getId());
				content = contentDao.saveContent(content);
			}
			if (content.getSysId() != null && content.getSysId() > -1) {
				User2Content u2c = userDao.findUser2ContentBy(userSysId,
						IConstants.RelationID.U2C_IS_POSTER_OF.getId(), content.getSysId());
				if (u2c == null) {
					// create User 2 message coupon relation
					u2c = new User2Content();
					u2c.setUser(user);
					u2c.setRelationId(IConstants.RelationID.U2C_IS_POSTER_OF.getId());
					u2c.setContent(content);
					u2c = userDao.saveUser2Content(u2c);
				}
				// -----clear site2content ------------
				Integer[] relationIds = { IConstants.RelationID.S2C_IS_POSTEE_OF.getId() };
				Integer[] contentTypeIds = { IConstants.Type.CONTENT_MESSAGE.getId() };
				List<Site2Content> s2cs = siteDao.getListSite2ContentBy(-1, relationIds, content.getSysId(), null,
						contentTypeIds, null, null, 0, 100, null);
				if (s2cs != null) {
					for (int i = 0; i < s2cs.size(); i++) {
						Site2Content s2c = s2cs.get(i);
						if (s2c.getStatus() != IConstants.Status.IS_APPROVE_FAIL.getId()) {
							siteDao.updateSite2ContentStatus(s2c.getSite().getSysId(), relationIds, content.getSysId(),
									IConstants.Status.IS_EDITING.getId());
						}
					}
				}
				if (post2SiteSysIds != null && post2SiteSysIds.length > 0) {
					// create Site 2 message coupon relation
					for (int i = 0; i < post2SiteSysIds.length; i++) {
						Site site = siteDao.findSiteBySysId(post2SiteSysIds[i]);
						if (site != null) {
							Site2Content s2c = siteDao.findSite2ContentBy(post2SiteSysIds[i],
									IConstants.RelationID.S2C_IS_POSTEE_OF.getId(), content.getSysId());
							if (s2c == null) {
								s2c = new Site2Content();
								s2c.setSite(site);
								s2c.setRelationId(IConstants.RelationID.S2C_IS_POSTEE_OF.getId());
								s2c.setContent(content);
							}

							if (s2c.getTypeId() != IConstants.Status.IS_APPROVE_FAIL.getId()) {
								// if not banned,then enable the relation
								// automatically
								s2c.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
							}

							s2c = siteDao.saveSite2Content(s2c);
						}
					}
				}
			}
		}
	}

	public List<User2Content> getListUserPostMessage(long userSysId, int pgno, int pgsize) {
		Integer[] relationIds = { IConstants.RelationID.U2C_IS_POSTER_OF.getId() };
		Integer[] contentTypeIds = { IConstants.Type.CONTENT_MESSAGE.getId() };
		return userDao
				.getListUser2ContentBy(userSysId, relationIds, -1, null, contentTypeIds, null, pgno, pgsize, null);
	}

	public User2Site findUserManagedHorde(long userSysId, long siteSysId) {
		User2Site result = null;
		if (userSysId > -1 || siteSysId > -1) {
			Integer[] relationIds = { IConstants.RelationID.U2S_IS_OWNER_OF.getId() };
			Integer[] siteTypeIds = { IConstants.Type.SITE_HORDE.getId() };
			List<User2Site> u2sList = userDao.getListUser2SiteBy(userSysId, relationIds, -1, null, siteTypeIds, 0, 1,
					null);
			// every user could only have max one managed horde
			if (u2sList != null && u2sList.size() > 0) {
				result = u2sList.get(0);
			}
		}
		return result;
	}

	public User2Site findStoreServant(long siteSysId) {
		User2Site result = null;
		if (siteSysId > -1) {
			Integer[] relationIds = { IConstants.RelationID.U2S_IS_SERVANT_OF.getId() };
			Integer[] siteTypeIds = { IConstants.Type.SITE_STORE.getId() };
			List<User2Site> u2sList = userDao.getListUser2SiteBy(-1, relationIds, siteSysId, null, siteTypeIds, 0, 1,
					null);
			// every user could only have max one managed horde
			if (u2sList != null && u2sList.size() > 0) {
				result = u2sList.get(0);
			}
		}
		return result;
	}

	public User2Content findProductServant(long contentSysId) {
		User2Content result = null;
		if (contentSysId > -1) {
			Integer[] relationIds = { IConstants.RelationID.U2C_IS_SERVANT_OF.getId() };
			Integer[] contentTypeIds = { IConstants.Type.CONTENT_PRODUCT.getId() };
			List<User2Content> u2cList = userDao.getListUser2ContentBy(-1, relationIds, contentSysId, null,
					contentTypeIds, null, 0, 1, null);
			// every coupon product only have one servant
			if (u2cList != null && u2cList.size() > 0) {
				result = u2cList.get(0);
			}
		}
		return result;
	}

	public void saveUserManagedHorde(long userSysId, Site pSite, String initStorePositionCategoryId) {
		User user = userDao.findUserBySysId(userSysId);
		Site theSite = siteDao.findSiteBySiteId(pSite.getSiteId());
		if (user != null && pSite != null && pSite.getSiteId() != null) {
			User2Site user2ManagedHorde = findUserManagedHorde(userSysId, -1);
			if (user2ManagedHorde == null && theSite == null) { // the site is
				// not managed
				// by others
				if (initStorePositionCategoryId != null) {
					Category category = categoryDao.findCategoryByCategoryId(initStorePositionCategoryId);
					if (category != null) {// require to add to a category
						// initially
						pSite.setTypeId(IConstants.Type.SITE_HORDE.getId());
						Site site = siteDao.saveSite(pSite);
						// save user2site
						User2Site u2s = new User2Site();
						u2s.setUser(user);
						u2s.setRelationId(IConstants.RelationID.U2S_IS_OWNER_OF.getId());
						u2s.setSite(site);
						userDao.saveUser2Site(u2s);
						// save site2Category
						Site2Category s2g = new Site2Category();
						s2g.setSite(site);
						s2g.setRelationId(IConstants.RelationID.S2G_IS_MEMBER_OF.getId());
						s2g.setCategory(category);
						siteDao.saveSite2Category(s2g);
					}
				}
			} else if (theSite.getSysId().compareTo(user2ManagedHorde.getSite().getSysId()) == 0
					&& user2ManagedHorde.getSite().getSysId().compareTo(pSite.getSysId()) == 0) {
				// the site is managed by the user
				siteDao.saveSite(pSite);
			}
		}
	}

	public User2Site findUserHomeHorde(long userSysId) {
		User2Site result = null;
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_HOMER_OF.getId() };
		Integer[] siteTypeIds = { IConstants.Type.SITE_HORDE.getId() };
		List<User2Site> u2sList = userDao.getListUser2SiteBy(userSysId, relationIds, -1, null, siteTypeIds, 0, 1, null);
		if (u2sList != null && u2sList.size() > 0)
			result = u2sList.get(0);
		return result;
	}

	public void setUserHomeHorde(long userSysId, long siteSysId) {
		Site site = siteDao.findSiteBySysId(siteSysId);
		if (site.getTypeId().compareTo(IConstants.Type.SITE_HORDE.getId()) == 0) {
			User2Site u2s = findUserHomeHorde(userSysId);
			if (u2s != null) {
				if (u2s.getSite().getSysId() != siteSysId) {
					u2s.setSite(site);
					userDao.saveUser2Site(u2s);
				}
			} else {
				u2s = new User2Site();
				User user = userDao.findUserBySysId(userSysId);
				u2s.setUser(user);
				u2s.setRelationId(IConstants.RelationID.U2S_IS_HOMER_OF.getId());
				u2s.setSite(site);
				userDao.saveUser2Site(u2s);
			}
		}
	}

	public User2Site findUserManagedWebSite(long userSysId) {
		User2Site result = null;
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_OWNER_OF.getId() };
		Integer[] siteTypeIds = { IConstants.Type.SITE_WEBSITE.getId() };
		List<User2Site> u2sList = userDao.getListUser2SiteBy(userSysId, relationIds, -1, null, siteTypeIds, 0, 1, null);
		// every user could only have max one managed website
		if (u2sList != null && u2sList.size() > 0)
			result = u2sList.get(0);
		return result;
	}

	public void saveUserManagedWebSite(long userSysId, Site pSite, String initWebSitePositionCategoryId) {
		User user = userDao.findUserBySysId(userSysId);
		Site theSite = siteDao.findSiteBySiteId(pSite.getSiteId());
		if (user != null && pSite != null && pSite.getSiteId() != null) {
			User2Site userManSite = findUserManagedWebSite(userSysId);
			if (userManSite == null && theSite == null) { // the site is not
				// managed by others
				if (initWebSitePositionCategoryId != null) {
					Category category = categoryDao.findCategoryByCategoryId(initWebSitePositionCategoryId);
					if (category != null) {// require to add to a category
						// initially
						pSite.setTypeId(IConstants.Type.SITE_WEBSITE.getId());
						Site site = siteDao.saveSite(pSite);
						// save user2site
						User2Site u2s = new User2Site();
						u2s.setUser(user);
						u2s.setRelationId(IConstants.RelationID.U2S_IS_OWNER_OF.getId());
						u2s.setSite(site);
						userDao.saveUser2Site(u2s);
						// save site2Category
						Site2Category s2g = new Site2Category();
						s2g.setSite(site);
						s2g.setRelationId(IConstants.RelationID.S2G_IS_MEMBER_OF.getId());
						s2g.setCategory(category);
						siteDao.saveSite2Category(s2g);
					}
				}
			} else if (theSite != null && theSite.getSysId().compareTo(userManSite.getSite().getSysId()) == 0
					&& userManSite != null && userManSite.getSite().getSysId().compareTo(pSite.getSysId()) == 0) {// the site is managed
				// by me
				siteDao.saveSite(pSite);
			}
		}
	}

	public void saveUserServedWebSite(long userSysId, Site pSite, String initWebSitePositionCategoryId) {
		User user = userDao.findUserBySysId(userSysId);
		Site theSite = siteDao.findSiteBySiteId(pSite.getSiteId());
		if (user != null && pSite != null && pSite.getSiteId() != null) {
			User2Site userServedWebSite = findUserServedWebSite(userSysId, pSite.getSiteId());
			if (userServedWebSite == null && theSite == null) { // the site is
				// not managed
				// by others
				if (initWebSitePositionCategoryId != null) {
					Category category = categoryDao.findCategoryByCategoryId(initWebSitePositionCategoryId);
					if (category != null) {// require to add to a category
						// initially
						pSite.setTypeId(IConstants.Type.SITE_WEBSITE.getId());
						Site site = siteDao.saveSite(pSite);
						// save user2site
						User2Site u2s = new User2Site();
						u2s.setUser(user);
						u2s.setRelationId(IConstants.RelationID.U2S_IS_SERVANT_OF.getId());
						u2s.setSite(site);
						userDao.saveUser2Site(u2s);
						// save site2Category
						Site2Category s2g = new Site2Category();
						s2g.setSite(site);
						s2g.setRelationId(IConstants.RelationID.S2G_IS_MEMBER_OF.getId());
						s2g.setCategory(category);
						siteDao.saveSite2Category(s2g);
					}
				}
			} else if (theSite != null && userServedWebSite != null
					&& theSite.getSysId().compareTo(userServedWebSite.getSite().getSysId()) == 0
					&& userServedWebSite.getSite().getSysId().compareTo(pSite.getSysId()) == 0) {// the site is managed
				// by me
				siteDao.saveSite(pSite);
			}
		}
	}

	public void addUserFavoriteWebSite(long userSysId, long siteSysId) {
		// TODO should limit favorite website number,check whether it is already
		// exist

		Site c = siteDao.findSiteBySysId(siteSysId);
		if (c != null && c.getTypeId().compareTo(IConstants.Type.SITE_WEBSITE.getId()) == 0) {
			Integer[] relationIds = { IConstants.RelationID.U2S_IS_FAVORITER_OF.getId() };

			List<User2Site> u2ss = userDao
					.getListUser2SiteBy(userSysId, relationIds, siteSysId, null, null, 0, 1, null);
			if (u2ss != null && u2ss.size() > 0) {
				User2Site u2s = u2ss.get(0);
				if (u2s.getStatus() != IConstants.Status.IS_APPROVE_SUCC.getId()) {
					u2s.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
				}
			} else {// create new User2Site
				User u = userDao.findUserBySysId(userSysId);
				if (u != null) {
					User2Site u2c = new User2Site();
					u2c.setUser(u);
					u2c.setRelationId(IConstants.RelationID.U2S_IS_FAVORITER_OF.getId());
					u2c.setSite(c);
					u2c.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
					userDao.saveUser2Site(u2c);
				}

			}
		}
	}

	public void saveUserFloatBook(long userSysId, User2Content user2Content, long[] floatInSiteSysIds) {
		if (user2Content != null && user2Content.getContent() != null) {
			User user = userDao.findUserBySysId(userSysId);
			Content content = user2Content.getContent();
			User2Content u2c = userDao.findUser2ContentBy(userSysId, IConstants.RelationID.U2C_IS_FLOATER_OF.getId(),
					content.getSysId());
			if (u2c == null) {
				u2c = new User2Content();
				u2c.setUser(user);
				u2c.setRelationId(IConstants.RelationID.U2C_IS_FLOATER_OF.getId());
				u2c.setContent(content);
			}
			u2c.setLongDesc(user2Content.getLongDesc());
			u2c = userDao.saveUser2Content(u2c);

			if (floatInSiteSysIds != null) {
				// save DeltaRelation to indicate float book in sites
				for (int i = 0; i < floatInSiteSysIds.length; i++) {
					Site site = siteDao.findSiteBySysId(floatInSiteSysIds[i]);
					if (site != null) {
						DeltaRelation delta = deltaUCSGRelationDao.findDeltaRelation(site.getSysId(), Site.class
								.getName(), IConstants.RelationID.S2UC_IS_FLOATEE_OF.getId(), u2c.getSysId(),
								User2Content.class.getName());
						if (delta == null) {
							delta = new DeltaRelation();
							delta.setSite(site);
							delta.setRelationId(IConstants.RelationID.S2UC_IS_FLOATEE_OF.getId());
							delta.setUser2Content2(u2c);
							deltaUCSGRelationDao.save(delta);
						}
					}
				}
			}
		}
	}

	public List<DeltaRelation> getListSiteUserFloatBook(long siteSysId, int pgno, int pgsize) {
		List<DeltaRelation> result = null;
		Site site = siteDao.findSiteBySysId(siteSysId);
		if (site != null) {
			result = deltaUCSGRelationDao.getListDeltaRelation(site.getSysId(), Site.class.getName(),
					IConstants.RelationID.S2UC_IS_FLOATEE_OF.getId(), -1, User2Content.class.getName(), pgno, pgsize);
		}
		return result;
	}

	public void saveUserFloatBookRepliedMessage(long userSysId, DeltaRelation delta, long user2ContentSysId) {
		User user = userDao.findUserBySysId(userSysId);
		User2Content user2Content = userDao.findUser2ContentBy(user2ContentSysId);
		if (user != null && user2Content != null) {
			DeltaRelation dt = new DeltaRelation();
			dt.setUser(user);
			dt.setRelationId(IConstants.RelationID.U2UC_IS_REPLIER_OF.getId());
			dt.setUser2Content2(user2Content);
			dt.setName(delta.getName());
			dt.setLongDesc(delta.getLongDesc());
			deltaUCSGRelationDao.save(dt);
		}
	}

	public List<DeltaRelation> getlistUserFloatBookRepliedMessage(long user2ContentSysId, int pgno, int pgsize) {
		List<DeltaRelation> result = null;
		User2Content u2c = userDao.findUser2ContentBy(user2ContentSysId);
		if (u2c != null) {
			result = deltaUCSGRelationDao.getListDeltaRelation(-1, User.class.getName(),
					IConstants.RelationID.U2UC_IS_REPLIER_OF.getId(), user2ContentSysId, User2Content.class.getName(),
					pgno, pgsize);
		}
		return result;
	}

	public Map<String, Object> getUserServedStores(long userSysId, long siteSysId, int pgno, int pgsize) {
		Map<String, Object> result = new HashMap<String, Object>();
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_SERVANT_OF.getId() };
		Integer[] statusIds = null;// {
		// IConstants.Status.IS_APPROVE_SUCC.getId()
		// };
		Integer[] siteTypeIds = { IConstants.Type.SITE_STORE.getId() };

		List<User2Site> u2cs = userDao.getListUser2SiteBy(userSysId, relationIds, siteSysId, statusIds, siteTypeIds,
				pgno, pgsize, null);
		long totalCount = userDao.getCountUser2SiteBy(userSysId, relationIds, siteSysId, statusIds, siteTypeIds);
		result.put("user2SiteList", u2cs);
		result.put("totalCount", new Long(totalCount));
		return result;
	}

	public void deleteUserFavoriteWebSite(long userSysId, long siteSysId) {
		// update the User2Site status to deleted.
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_FAVORITER_OF.getId() };
		Integer[] siteTypeIds = { IConstants.Type.SITE_WEBSITE.getId() };
		List<User2Site> u2ss = userDao.getListUser2SiteBy(userSysId, relationIds, siteSysId, null, siteTypeIds, 0, 1,
				null);
		if (u2ss != null && u2ss.size() > 0) {
			User2Site u2s = u2ss.get(0);
			u2s.setStatus(IConstants.Status.IS_APPROVE_FAIL.getId());
			userDao.saveUser2Site(u2s);
		}
	}

	public Site2Site saveUserHorde2Store(long userSysId, Site2Site site2Site) {
		Site2Site result = null;
		User2Site userManagedHorde = this.findUserManagedHorde(userSysId, -1);
		if (site2Site != null && site2Site.getSite() != null
				&& site2Site.getSite().getSysId().compareTo(userManagedHorde.getSite().getSysId()) == 0) {
			result = siteDao.saveSite2Site(site2Site);
		}
		return result;
	}

	public Map<String, Object> getUserServedProducts(long userSysId, long contentSysId, int pgno, int pgsize) {
		Map<String, Object> result = new HashMap<String, Object>();

		Integer[] relationIds = { IConstants.RelationID.U2C_IS_SERVANT_OF.getId() };
		Integer[] contentTypeIds = { IConstants.Type.CONTENT_PRODUCT.getId() };
		List<User2Content> u2cList = userDao.getListUser2ContentBy(userSysId, relationIds, contentSysId, null,
				contentTypeIds, null, pgno, pgsize, null);
		long totalCount = userDao.getCountUser2ContentBy(userSysId, relationIds, contentSysId, null, contentTypeIds,
				null);
		result.put("user2ContentList", u2cList);
		result.put("totalCount", new Long(totalCount));
		return result;
	}

	public void saveUserServedProduct(long userSysId, Content content, String contentCategoryId, String brandCategoryId) {
		Content c = contentDao.findContentByContentId(content.getContentId());
		if (c != null && c.getSysId().compareTo(content.getSysId()) == 0) {
			contentDao.saveContent(content);
		} else if (c == null) {// new coupon
			User user = userDao.findUserBySysId(userSysId);
			Category g = categoryDao.findCategoryByCategoryId(contentCategoryId);
			if (user != null && g != null) {
				content.setTypeId(IConstants.Type.CONTENT_PRODUCT.getId());
				c = contentDao.saveContent(content);
				// create User2Content
				User2Content u2c = new User2Content();
				u2c.setUser(user);
				u2c.setRelationId(IConstants.RelationID.U2C_IS_SERVANT_OF.getId());
				u2c.setContent(c);
				userDao.saveUser2Content(u2c);
				// create Content2Category
				Content2Category c2g = new Content2Category();
				c2g.setContent(c);
				c2g.setRelationId(IConstants.RelationID.C2G_IS_MEMBER_OF.getId());
				c2g.setCategory(g);
				contentDao.saveContent2Category(c2g);
				// create content2Category of brand category
				if (brandCategoryId != null) {
					Category bg = categoryDao.findCategoryByCategoryId(brandCategoryId);
					if (bg != null) {
						Content2Category c2bg = new Content2Category();
						c2bg.setContent(c);
						c2bg.setRelationId(IConstants.RelationID.C2G_IS_BRAND_MEMBER_OF.getId());
						c2bg.setCategory(bg);
						contentDao.saveContent2Category(c2bg);
					}
				}
			}
		}

	}

	public Map<String, Object> getUserServedWebSites(long userSysId, long webSiteSysId, int pgno, int pgsize) {
		Map<String, Object> result = new HashMap<String, Object>();
		Integer[] relationIds = { IConstants.RelationID.U2S_IS_SERVANT_OF.getId() };
		Integer[] statusIds = null;// {
		// IConstants.Status.IS_APPROVE_SUCC.getId()
		// };
		Integer[] siteTypeIds = { IConstants.Type.SITE_WEBSITE.getId() };

		List<User2Site> u2cs = userDao.getListUser2SiteBy(userSysId, relationIds, webSiteSysId, statusIds, siteTypeIds,
				pgno, pgsize, null);
		long totalCount = userDao.getCountUser2SiteBy(userSysId, relationIds, webSiteSysId, statusIds, siteTypeIds);
		result.put("user2SiteList", u2cs);
		result.put("totalCount", new Long(totalCount));
		return result;
	}

	public User2Site findUserServedWebSite(long userSysId, String webSiteId) {
		Site site = siteDao.findSiteBySiteId(webSiteId);
		if (site != null) {
			User2Site result = null;
			Integer[] relationIds = { IConstants.RelationID.U2S_IS_SERVANT_OF.getId() };
			Integer[] siteTypeIds = { IConstants.Type.SITE_WEBSITE.getId() };
			List<User2Site> u2sList = userDao.getListUser2SiteBy(userSysId, relationIds, site.getSysId(), null,
					siteTypeIds, 0, 1, null);
			// every user could only have max one managed website
			if (u2sList != null && u2sList.size() > 0)
				result = u2sList.get(0);
			return result;

		}
		return null;
	}

	public User2User setUserRecommender(long recommenderSysId, long userSysId) {
		User2User result = null;
		User recommender = userDao.findUserBySysId(recommenderSysId);
		User user = userDao.findUserBySysId(userSysId);
		if (recommender != null && user != null) {
			Integer relationId = IConstants.RelationID.U2U_IS_RECOMMENDER_OF.getId();
			User2User user2User = this.findUserRecommender(userSysId);
			if (user2User == null) {
				user2User = new User2User();
				user2User.setRelationId(relationId);
				user2User.setUser2(user);
				user2User.setUser(recommender);
				result = userDao.saveUser2User(user2User);
			} else {
				// Error , the user has already had a recommender
				result = user2User;
			}
		}
		return result;
	}

	public void resetUserRecommender(long userSysId) {
		User2User user2User = this.findUserRecommender(userSysId);
		if (user2User != null) {
			user2User.setUser(null);
			user2User = userDao.saveUser2User(user2User);
		}
	}

	public User2User findUserRecommender(long userSysId) {
		Integer relationId = IConstants.RelationID.U2U_IS_RECOMMENDER_OF.getId();
		User2User user2User = userDao.findUser2UserBy(-1, relationId, null, userSysId);
		return user2User;
	}

	public List<User2User> getListUserRecommendee(long userSysId) {
		Integer[] relationIds = { IConstants.RelationID.U2U_IS_RECOMMENDER_OF.getId() };
		List<User2User> user2UserList = userDao.getListUser2UserBy(userSysId, relationIds, null, -1, 0, 6, null);
		return user2UserList;
	}

	public User2Site approve2BeStoreServant(long userSysId, long user2SiteSysId) {
		User2Site result = null;
		User user = userDao.findUserBySysId(userSysId);

		if (user2SiteSysId > -1 && user != null) {
			User2Site user2Site = userDao.findUser2SiteBy(user2SiteSysId);
			if (user2Site != null
					&& user2Site.getUser() != null
					&& user2Site.getUser().getSysId().compareTo(user.getSysId()) == 0 // it is me
					&& user2Site.getRelationId().compareTo(IConstants.RelationID.U2S_IS_SERVANT_OF.getId()) == 0
					&& (user2Site.getStatus() == null || user2Site.getStatus().compareTo(
							IConstants.Status.IS_APPROVE_SUCC.getId()) != 0)) {
				user2Site.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
				result = userDao.saveUser2Site(user2Site);
			}
		}

		return result;
	}

	public User2Site requestStoreServant(long siteSysId, String userId) {
		User2Site result = null;
		User user = userDao.findUserByUserId(userId);
		if (siteSysId > -1 && user != null) {
			// check whether the user is a servant
			User2User recommender = this.findUserRecommender(user.getSysId());
			if (recommender != null) {
				Map<String, Object> u2sMap = this.getUserServedStores(user.getSysId(), siteSysId, 0, 1);
				List<User2Site> u2sList = (List<User2Site>) u2sMap.get("user2SiteList");
				if (u2sList == null || u2sList.size() == 0) {
					Site site = siteDao.findSiteBySysId(siteSysId);
					User2Site u2s = new User2Site();
					u2s.setUser(user);
					u2s.setRelationId(IConstants.RelationID.U2S_IS_SERVANT_OF.getId());
					u2s.setSite(site);
					u2s.setStatus(IConstants.Status.IS_APPROVING.getId());
					result = userDao.saveUser2Site(u2s);
				}
			}
		}

		return result;
	}

	public User2Site approveUserServedStore(long userSysId, User2Site user2Store) {
		User2Site result = null;
		User user = userDao.findUserBySysId(userSysId);
		if (user != null && user2Store != null && user.getSysId().compareTo(user2Store.getUser().getSysId()) == 0) {
			siteDao.saveSite(user2Store.getSite());// update site's status
			result = userDao.saveUser2Site(user2Store); // updateg user2Site
			// shortdesc，审批说明
		}
		return result;
	}

	public TagLog saveTagLog(long userSysId, TagLog tagLog) {
		User user = userDao.findUserBySysId(userSysId);
		TagLog result = null;
		if (user != null && tagLog != null && tagLog.getSrcUrl() != null && !tagLog.getSrcUrl().trim().equals("")) {
			tagLog.setUser(user);
			tagLog.setStatus(IConstants.Status.IS_EDITING.getId());
			result = userDao.saveTagLog(tagLog);
		}

		return result;
	}
}
